基础知识
概念
Java代码的阶段
- Java代码在计算机中经历的三个阶段
- Source(源代码阶段)
- Java文件被Javac编译为class文件,class文件会将成员变量、成员方法和构造方法等编译成不同的模块。
- class文件通过 Classload类加载器 来进入和下一阶段。
- Class(类对象阶段)
- 通过 Classload类加载器,将class文件加载进内存,成员变量、成员方法和构造方法会被封装为Class类中的对象。
- Runtime(运行阶段)
- 当我们需要访问Java文件的成员时,我们就可以逆向访问,通过Class类的Classload类加载器来获取该成员的对象。
- Source(源代码阶段)
获取Class对象
- Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象。
- 处于Source(源代码阶段),并未加载进内存。
- 用于配置文件,将类名定义在配置文件中。读取文件,从而加载类。
- 处于Source(源代码阶段),并未加载进内存。
- 类名.class:通过类名的属性class获取。
- 处于Class(类对象阶段),已经加载进内存。
- 多用于参数的传递。
- 处于Class(类对象阶段),已经加载进内存。
- 对象.getClass():Object类中定义的方法。
- Runtime(运行阶段),处于运行时。
- 用于获取对象的字节码文件对象。
- Runtime(运行阶段),处于运行时。
- Class类对象
- 同一个字节码文件( .class)在一次程序运行过程中,只会被加载一次。
- 不论通过哪一种方式获取的Class类对象都是同一个。
1
2
3
4
5
6
7
8
// Class类.静态方法forName("全类名")
Class class1 = Class.forName("com.test.Person");
// 类名.成员class
Class class2 = Person.class;
// 对象名.成员方法getClass()
Person person = new Person();
Class class3 = person.getClass();
获取成员变量
- Field[] getFields()
- 返回包含一个 Field对象数组,反射 所有可访问的 public字段类对象。
- Field getField(String name)
- 返回一个 Field对象,反射 指定的 public成员字段类对象。
- Field[] getDeclaredFields()
- 返回一个 Field对象,反射 所有可访问的 已声明字段类对象。(不考虑修饰符)
- Field getDeclaredField(String name)
- 返回一个 Field对象数组,反射 指定已声明字段类对象。(不考虑修饰符)
Person类中的成员变量
- 返回一个 Field对象数组,反射 指定已声明字段类对象。(不考虑修饰符)
1 | // public修饰符 |
获取Person类中的成员变量
1 |
|
获取构造方法
- Constructor<?>[] getConstructors()
- 返回一个 Constructor对象,反射 指定的 public构造类对象。
- Constructor<T> getDeclaredConstructor(类<?>… parameterTypes)
- 返回一个 Constructor对象,反射 指定的 构造类对象。
- Constructor<T> getConstructor(类<?>… parameterTypes)
- 返回一个 Constructor对象数组,反射 所有的 public构造类对象。
- Constructor<?>[] getDeclaredConstructors()
- 返回一个 Constructor对象数组,反射 所有定的 构造类对象。
Person类中的构造方法
1 |
|
获取Person类中的构造方法
1 |
|
获取成员方法
- Method getMethod(String name, 类<?>… parameterTypes)
- 返回一个 Method对象,反射 指定的 public成员方法类对象。
- Method getDeclaredMethod(String name, 类<?>… parameterTypes)
- 返回一个 Method对象,反射 指定的 成员方法类对象。
- Method[] getMethods()
- 返回一个 Method对象数组,反射 所有的 public成员方法类对象。
- Method[] getDeclaredMethods()
- 返回一个 Method对象数组,反射 所有的 成员方法类对象。
Person类中的成员方法
1 |
|
获取Person类中的成员方法
1 |
|
获取全类名
- String getName()
其他操作
操作Field
- 设置值
- void set(Object obj, Object value)
- 获取值
- get(Object obj)
- 暴力反射:忽略访问权限修饰符的安全检查
- setAccessible(true):暴力反射
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Class pc = Person.class;
Person p = new Person();
/*public修饰符*/
Field fie = pc.getField("publicName");
// public java.lang.String test.Person.publicName
fie.set(p,"cat");
System.out.print( fie.get(p) );
// cat
/*private修饰符*/
Field fie = pc.getDeclaredField("privateName");
// private java.lang.String test.Person.privateName
pc.setAccessible(true);
pc.set(p,"dog");
System.out.print( fie.get(p) );
// dog
- setAccessible(true):暴力反射
操作Constructor
- 创建对象
- T newInstance(Object… initargs)
- 如果使用空参数构造方法创建对象,操作可以简化
- Class对象的newInstance方法
1 |
|
操作Method
- 执行方法
- Object invoke(Object obj, Object… args)
- 获取方法名
- String getName
1
2
3
4
5Class pc = Person.class;
Person p = new Person();
Method method = personClass.getMethod("publicMethod111");
method.invoke(p);
// publicMethod()...
- String getName